package com.esfak47.mediafetcher.plugin.pornhub.service.impl;

import com.esfak47.common.lang.Assert;
import com.esfak47.common.logger.Logger;
import com.esfak47.common.logger.LoggerFactory;
import com.esfak47.common.utils.StringUtils;
import com.esfak47.mediafetcher.core.domain.FetchAble;
import com.esfak47.mediafetcher.core.domain.Media;
import com.esfak47.mediafetcher.core.domain.VideoExtInfo;
import com.esfak47.mediafetcher.core.service.CrawlerService;
import com.google.gson.Gson;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.function.Supplier;

/**
 * @author tony
 */

public class YoudlCrawlerServiceImpl implements CrawlerService {

    private final static Logger log = LoggerFactory.getLogger(YoudlCrawlerServiceImpl.class);
    private static final String DEFAULT_YOUTUBE_DL_LOCATION = "/usr/local/bin/youtube-dl";

    private String binPath;

    public YoudlCrawlerServiceImpl() {
        String property = System.getProperty("youtube-dl.location");
        if (StringUtils.isEmpty(property)) {
            property = DEFAULT_YOUTUBE_DL_LOCATION;
        }
        this.binPath = property;
    }

    @Override
    public CompletableFuture<Optional<Media>> getVideoExtInfoAsync(FetchAble fetchAble) {
        Assert.notNull(fetchAble, "fetchable should not be null");

        return CompletableFuture.supplyAsync(
            getExtraInfo(fetchAble));
    }

    @Override
    public Optional<Media> getVideoExtInfo(FetchAble fetchAble) {
        return getExtraInfo(fetchAble).get();
    }

    @Override
    public Supplier<Optional<Media>> getExtraInfo(FetchAble fetchAble) {
        return () -> {

            ProcessBuilder processBuilder = new ProcessBuilder(
                Arrays.asList(binPath, "-j", fetchAble.getLocation()));
            try {
                Process start = processBuilder.start();
                InputStream inputStream = start.getInputStream();
                Gson gson = new Gson();
                VideoExtInfo videoExtInfo = gson.fromJson(
                    new BufferedReader(new InputStreamReader(inputStream)), VideoExtInfo.class);
                if (videoExtInfo != null) {
                    videoExtInfo.setFetchAble(fetchAble);
                    if (fetchAble.getType().equals("pornhub")) {
                        return Optional.of(PornHubMediaProvider.videoExtInfoConverter(videoExtInfo));
                    }
                }
                return Optional.empty();
            } catch (IOException e) {
                log.error("fetch data failed", e);
                return Optional.empty();
            }
        };
    }
}
